import 'package:flutter/material.dart';
import 'package:card_swiper/card_swiper.dart';

import '../../widgets/block_widget.dart';
import '../../widgets/tags/menu_item.dart';
import '../../models/article_model.dart';
import '../../models/list_result.dart';
import '../../utils/api.dart';
import '../../widgets/article_widget.dart';
import '../../utils/tools.dart';
import '../../config.dart';
import '../../models/category_model.dart';
import '../../application.dart';
import 'cate_row.dart';

class IndexPage extends StatefulWidget {
  final String channel;

  const IndexPage({Key? key, this.channel = ''}) : super(key: key);

  @override
  State<IndexPage> createState() => _IndexPageState();
}

class _IndexPageState extends State<IndexPage>
    with AutomaticKeepAliveClientMixin<IndexPage> {
  late CategoryModel channel;
  late List<CategoryModel> categories;
  List<dynamic>? _banners;
  List<CategoryModel>? _catesWithArts;
  ListResult? _articles;
  bool initialized = false;
  bool _isLoading = true;
  bool _isError = false;

  final ScrollController _controller = ScrollController();

  @override
  void initState() {
    super.initState();
    initialize();
  }

  Widget _renderBanner() {
    var theme = Theme.of(context);
    //logger.info(bannerWidth.toString()+'/'+ bannerHeight.toString());
    //if(_banners != null)logger.info(_banners.length);
    return (_banners == null || _banners!.isEmpty)
        ? Container(
            color: theme.colorScheme.surface,
          )
        : _BannerWidget(_banners!);
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    if (!initialized) {
      return const Center(
        child: CircularProgressIndicator(),
      );
    }
    final colorScheme = Theme.of(context).colorScheme;
    final cateItemWidth =
        ((MediaQuery.of(context).size.width - 50) ~/ 4).toDouble();
    final iconSize = (cateItemWidth ~/ 2).toDouble();
    final rowCount = categories.length >= 6 ? 2 : 1;
    return Scaffold(
      body: SafeArea(
        child: RefreshIndicator(
          onRefresh: () {
            return initialize(force: true);
          },
          child: CustomScrollView(
            physics: const AlwaysScrollableScrollPhysics()
              ..applyTo(const BouncingScrollPhysics()),
            primary: true,
            slivers: [
              if (_banners != null && _banners!.isNotEmpty)
                SliverAppBar(
                  flexibleSpace: FlexibleSpaceBar(
                    background: _renderBanner(),
                    //titlePadding: EdgeInsets.only(right: 50.0),
                    //centerTitle: true,
                    collapseMode: CollapseMode.parallax,
                  ),
                ),
              SliverToBoxAdapter(
                child: BlockWidget(
                  margin: const EdgeInsets.all(20),
                  decoration: BoxDecoration(
                    color: colorScheme.surface,
                    borderRadius: const BorderRadius.all(Radius.circular(5)),
                  ),
                  child: Scrollbar(
                    thumbVisibility: true,
                    controller: _controller,
                    child: SingleChildScrollView(
                      scrollDirection: Axis.horizontal,
                      controller: _controller,
                      primary: false,
                      child: ConstrainedBox(
                        constraints: BoxConstraints(
                            maxWidth: (categories.length + 1) ~/
                                rowCount *
                                cateItemWidth),
                        child: Padding(
                          padding: const EdgeInsets.symmetric(vertical: 15),
                          child: Wrap(
                            children: categories
                                .map<Widget>((item) => TagMenuItem(
                                      size: cateItemWidth,
                                      aspectRatio: 0.8,
                                      onTap: () {
                                        app.route(
                                          '/channel/list',
                                          arguments: {
                                            'channel': widget.channel,
                                            'cate': item.id,
                                          },
                                        );
                                      },
                                      icon: SizedBox(
                                        width: iconSize,
                                        child: ClipOval(
                                          child: AspectRatio(
                                            aspectRatio: 1,
                                            child: Tools.image(item.icon),
                                          ),
                                        ),
                                      ),
                                      text: item.title,
                                    ))
                                .toList(),
                          ),
                        ),
                      ),
                    ),
                  ),
                ),
              ),
              if (_articles != null && _articles!.hasList)
                SliverList(
                  delegate: SliverChildBuilderDelegate(
                    (context, index) {
                      return Padding(
                        padding: const EdgeInsets.only(
                            left: 10, right: 10, bottom: 5),
                        child: ArticleWidget(
                            ArticleModel.fromJson(
                                _articles?.lists?[index] as Map?),
                            cols: 2),
                      );
                    },
                    childCount: _articles?.lists?.length ?? 0,
                  ),
                ),
              if (_catesWithArts != null && _catesWithArts!.isNotEmpty)
                SliverList(
                  delegate: SliverChildBuilderDelegate(
                    (context, index) {
                      final item = _catesWithArts![index];
                      return Padding(
                        padding: const EdgeInsets.only(
                            left: 10, right: 10, bottom: 5),
                        child: CateRow(
                          cate: item,
                          channel: widget.channel,
                          lists: item.lists,
                        ),
                      );
                    },
                    childCount: _catesWithArts?.length ?? 0,
                  ),
                ),
            ],
          ),
        ),
      ),
    );
  }

  Future<void> initialize({bool force = false}) async {
    final allCates = await app.getCategories(force: force);
    if (allCates[0] != null) {
      if (widget.channel.isEmpty) {
        channel = allCates[0]!.firstWhere((element) => element.isTop,
            orElse: () => CategoryModel());
      } else {
        channel = allCates[0]!.firstWhere(
            (element) => element.name == widget.channel,
            orElse: () => CategoryModel());
      }
      categories = allCates[channel.id] ?? [];
    } else {
      channel = CategoryModel();
    }
    initialized = true;
    if (mounted) {
      setState(() {});
      _loadData();
    }
  }

  Future<void> _loadData() async {
    final result = await Api.post('common/batch', {
      'article.get_cates': {
        'pid': channel.id,
        'list_count': 5,
      },
      'advs': {'flag': channel.name}
    });
    _isLoading = false;
    if (!mounted) return;
    if (result.code == 1 && result.data != null) {
      final data = result.data!;

      setState(() {
        _banners = data['advs'];
        _articles = ListResult<ArticleModel>.fromJson(
            data['article.get_list'], (dat) => ArticleModel.fromJson(dat));
        _catesWithArts = data['article.get_cates']
            ?.map<CategoryModel>((item) => CategoryModel.fromJson(item))
            .toList();
      });
    } else {
      setState(() {
        _isError = true;
      });
    }
  }

  @override
  bool get wantKeepAlive => true;
}

class _BannerWidget extends StatelessWidget {
  final List _banners;

  const _BannerWidget(this._banners, {Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    var bannerWidth = size.width;
    var bannerHeight = size.width * .6;

    return Swiper(
      itemWidth: bannerWidth,
      itemHeight: bannerHeight,
      viewportFraction: 0.9,
      scale: 0.95,
      itemBuilder: (context, idx) {
        //logger.info(json.encode(_banners[idx]));
        var item = _banners[idx] as Map<String, dynamic>;
        return Stack(
          fit: StackFit.expand,
          children: [
            Container(
              decoration: const BoxDecoration(
                borderRadius: BorderRadius.all(Radius.circular(10)),
              ),
              clipBehavior: Clip.antiAlias,
              margin: const EdgeInsets.symmetric(vertical: 10),
              child: Tools.image(
                Tools.fixImageUrl(item['image']),
                width: bannerWidth,
                height: bannerHeight,
              ),
            ),
            Align(
              alignment: Alignment.bottomCenter,
              heightFactor: 2,
              child: Padding(
                padding: const EdgeInsets.only(bottom: 25.0),
                child: Text(
                  item['title'],
                  style: const TextStyle(color: Colors.white),
                ),
              ),
            )
          ],
        );
      },
      itemCount: _banners.length,
      controller: SwiperController(),
      pagination: const SwiperPagination(),
    );
  }
}
